using System.Net.Http.Headers;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;

namespace LetCoding.CodeApi.Services;

public class GlotService(IHttpClientFactory httpClientFactory)
{
    // 仿照LANGUAGES数组
    private static readonly Dictionary<string, string?> Languages = new(StringComparer.OrdinalIgnoreCase)
    {
        { "assembly", "asm" }, { "ats", "dats" }, { "bash", "sh" }, { "c", "c" }, { "clojure", "clj" },
        { "cobol", "cob" }, { "coffeescript", "coffee" }, { "cpp", "cpp" }, { "crystal", "cr" },
        { "csharp", "cs" }, { "d", "d" }, { "elixir", "ex" }, { "elm", "elm" }, { "erlang", "erl" },
        { "fsharp", "fs" }, { "go", "go" }, { "groovy", "groovy" }, { "hare", "hare" }, { "haskell", "hs" },
        { "idris", "idr" }, { "java", "java" }, { "javascript", "js" }, { "julia", "jl" }, { "kotlin", "kt" },
        { "lua", "lua" }, { "mercury", "m" }, { "nim", "nim" }, { "nix", "nix" }, { "ocaml", "ml" },
        { "perl", "pl" }, { "php", "php" }, { "python", "py" }, { "raku", "raku" }, { "ruby", "rb" },
        { "rust", "rs" }, { "sac", "sac" }, { "scala", "scala" }, { "swift", "swift" }, { "typescript", "ts" },
        { "zig", "zig" }
    };

    /// <summary>
    /// 使用glot.io运行在线代码
    /// </summary>
    /// <param name="apiToken">API Token</param>
    /// <param name="code">要运行的代码</param>
    /// <param name="language">语言（如"javascript"，可选）</param>
    /// <param name="stdin">标准输入（可选）</param>
    /// <returns>结果字符串</returns>
    public async Task<string> RunGlotAsync(string apiToken, string code, string language = "javascript",
        string? stdin = null)
    {
        if (string.IsNullOrWhiteSpace(code))
            return "请输入代码";
        if (string.IsNullOrWhiteSpace(language))
            language = "javascript";

        // 查找对应后缀
        if (!Languages.TryGetValue(language, out var extension))
            return "不支持的语言";

        var url = $"https://glot.io/api/run/{language}/latest";

        // 构建post数据

        var data = new PostDataModel()
        {
            Files =
            [
                new PostFile()
                {
                    Name = $"main.{extension}",
                    Content = code
                }
            ],
            Stdin = stdin
        };

        using var client = httpClientFactory.CreateClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", apiToken);
        try
        {
            var response = await client.PostAsJsonAsync(url, data);
            var respStr = await response.Content.ReadAsStringAsync();
            if (!response.IsSuccessStatusCode)
                return "请求出错";

            var resp = JsonNode.Parse(respStr);
            var result = new RunResult
            {
                Stdout = resp!["stdout"]!.GetValue<string>(),
                Stderr = resp["stderr"]!.GetValue<string>()
            };

            // 兼容接口结构
            return !string.IsNullOrEmpty(result.Stderr)
                ? $"运行出错: {Escape(result.Stderr)}\n{Escape(result.Stderr)}"
                : Escape(result.Stdout + result.Stderr);
        }
        catch (Exception exception)
        {
            // 日志可以输出ex
            return $"请求出错: {exception}";
        }
    }

    /// <summary>
    /// 转义输出，防注入（简单实现）
    /// </summary>
    private static string Escape(string text)
    {
        return string.IsNullOrEmpty(text) ? "" : text.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
    }
}

public record PostDataModel
{
    [JsonPropertyName("files")] public List<PostFile> Files { get; set; } = [];

    [JsonPropertyName("stdin")] public string? Stdin { get; set; }
}

public record PostFile
{
    [JsonPropertyName("name")] public string Name { get; set; } = "";
    [JsonPropertyName("content")] public string Content { get; set; } = "";
}

public record RunResult
{
    [JsonPropertyName("stdout")] public string Stdout { get; set; } = "";
    [JsonPropertyName("stderr")] public string Stderr { get; set; } = "";
}